#include <iostream>
#include <sstream>
#include <fstream>
#include <map>
using std::cout;
using std::cerr;
using std::endl;
using std::string;
using std::ifstream;
using std::ofstream;
using std::istringstream;
using std::map;

class Dictionary{
public:
    void read(const string & filename);
    void store(const string & resultname);
    void display() const;
private:
    map<string,int> _dict;
};


void Dictionary::read(const string & filename){
    ifstream ifs(filename);
    if(!ifs.good()){
        cerr << "fail to open file" << endl;
        return;
    }

    string line;
    while(getline(ifs,line)){
        istringstream iss(line);
        string word;
        while(iss >> word){
            //处理数字问题
            bool hasDigit = false;
            for(auto & ch : word){
                if(isdigit(ch)){
                    hasDigit = true;
                    break;
                }
            }

            if(hasDigit){
                continue;
            }
            
            //处理标点符号
            //如果单词末尾出现符号，不统计
            if(ispunct(word.back())){
                continue;
            }

            //如果单词开头出现符号，不统计
            if(ispunct(word.front())){
                continue;
            }

            //如果单词首字母大写，转成小写
            if(isupper(word[0])){
                word[0] = tolower(word[0]);
            }

            #if 0
            auto it = _dict.find(word);
            if(it == _dict.end()){
                //没找到就插入一个pair
                //新出现的word的frequency初始化为1
                _dict.insert({word,1});
            }else{
                //找的就给对应的word的frequency+1
                //箭头运算符优先级高于前置++
                ++it->second;
            }
            #endif
            //利用了map的下标操作
            //如果找到word（key），返回对应的frequency(value)
            //对其进行+1
            //如果没找到word，会给这个map插入一个pair{新word,0}
            //再对新的word的frequency +1
            ++_dict[word];
        }
    }
    ifs.close();
}

void Dictionary::store(const string & filename){
    ofstream ofs(filename);
    for(auto & couple : _dict){
        ofs << couple.first << "  :  " << couple.second << endl;
    }
    ofs.close();
}

void Dictionary::display() const{
    for(auto & couple : _dict){
        cout << couple.first << "  :  " << couple.second << endl;
    }
}



void test0(){
    Dictionary dict;
    dict.read("The_Holy_Bible.txt");
    dict.store("result1.txt");
    dict.display();
}

int main(void){
    test0();
    return 0;
}
